package com.wanban.download.exo;


import android.os.Handler;
import android.os.Looper;

import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.DataSource;
import androidx.media3.exoplayer.drm.DrmSession;
import androidx.media3.exoplayer.drm.DrmSessionEventListener;
import androidx.media3.exoplayer.drm.OfflineLicenseHelper;
import androidx.media3.exoplayer.offline.DownloadHelper;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Downloads a Widevine offline license in a background thread.
 */
@UnstableApi
public class WidevineOfflineLicenseFetchTask {

    private final Format format;
    private final MediaItem.DrmConfiguration drmConfiguration;
    private final DataSource.Factory dataSourceFactory;
    private final DownloadHelper downloadHelper;
    private final ExecutorService executorService;

    @Nullable
    Future<?> future;
    @Nullable
    private byte[] keySetId;
    @Nullable
    private DrmSession.DrmSessionException drmSessionException;
    private final OnWidevineOfflineLicenseListener listener;

    public WidevineOfflineLicenseFetchTask(
            Format format,
            MediaItem.DrmConfiguration drmConfiguration,
            DataSource.Factory dataSourceFactory,
            DownloadHelper downloadHelper,
            OnWidevineOfflineLicenseListener offlineListener) {
        this.executorService = Executors.newSingleThreadExecutor();
        this.format = format;
        this.drmConfiguration = drmConfiguration;
        this.dataSourceFactory = dataSourceFactory;
        this.downloadHelper = downloadHelper;
        this.listener = offlineListener;
    }

    public void cancel() {
        if (future != null) {
            future.cancel(/* mayInterruptIfRunning= */ false);
        }
    }

    public void execute() {
        future =
                executorService.submit(
                        () -> {
                            OfflineLicenseHelper offlineLicenseHelper =
                                    OfflineLicenseHelper.newWidevineInstance(
                                            drmConfiguration.licenseUri.toString(),
                                            drmConfiguration.forceDefaultLicenseUri,
                                            dataSourceFactory,
                                            drmConfiguration.licenseRequestHeaders,
                                            new DrmSessionEventListener.EventDispatcher());
                            try {
                                keySetId = offlineLicenseHelper.downloadLicense(format);
                            } catch (DrmSession.DrmSessionException e) {
                                drmSessionException = e;
                            } finally {
                                offlineLicenseHelper.release();
                                new Handler(Looper.getMainLooper())
                                        .post(() -> {
                                            if (drmSessionException != null) {
                                                if (listener != null) {
                                                    listener.onOfflineLicenseFetchedError(drmSessionException);
                                                }

                                            } else {
                                                if (listener != null) {
                                                    listener.onOfflineLicenseFetched(downloadHelper, keySetId);
                                                }
                                            }
                                        });
                            }
                        });
    }


    public interface OnWidevineOfflineLicenseListener {
        void onOfflineLicenseFetchedError(DrmSession.DrmSessionException drmSessionException);
        void  onOfflineLicenseFetched(DownloadHelper downloadHelper, byte[] keySetId);

    }
}
